package org.jeecg.modules.wms.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.wms.entity.WmsInboundOrder;
import org.jeecg.modules.wms.entity.WmsInboundOrderDetail;
import org.jeecg.modules.wms.vo.WmsInboundOrderVO;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 入库单服务接口
 */
public interface IWmsInboundOrderService extends IService<WmsInboundOrder> {

    /**
     * 分页查询入库单列表
     * @param page 分页参数
     * @param params 查询参数
     * @return 分页结果
     */
    IPage<WmsInboundOrderVO> queryInboundOrderPageList(Page<WmsInboundOrderVO> page, Map<String, Object> params);

    /**
     * 创建入库单
     * @param wmsInboundOrder 入库单信息
     * @return 入库单号
     */
    String createInboundOrder(WmsInboundOrderVO wmsInboundOrder);
    
    /**
     * 创建余料入库单
     * @param wmsInboundOrder 入库单信息
     * @return 入库单号
     */
    String createSurplusInboundOrder(WmsInboundOrderVO wmsInboundOrder);
    
    /**
     * 自动创建订单的生产余料入库单
     * @param orderId 订单ID
     * @param outboundOrderId 出库单ID（可选，用于关联）
     * @return 入库单号，如果没有有效余料则返回null
     */
    String autoCreateSurplusInboundOrder(String orderId, String outboundOrderId);

    /**
     * 更新入库单
     * @param wmsInboundOrder 入库单信息
     * @return 是否成功
     */
    boolean updateInboundOrder(WmsInboundOrderVO wmsInboundOrder);

    /**
     * 根据ID获取入库单信息
     * @param id 入库单ID
     * @return 入库单信息
     */
    WmsInboundOrderVO getInboundOrderById(String id);

    /**
     * 获取入库单明细列表
     * @param inboundOrderId 入库单ID
     * @return 明细列表
     */
    List<WmsInboundOrderDetail> getDetailsByInboundOrderId(String inboundOrderId);

    /**
     * 确认入库
     * @param id 入库单ID
     * @param detailId 明细ID
     * @param actualWarehouseId 实际入库仓库ID
     * @param actualLocationId 实际入库库位ID
     * @param actualQuantity 实际入库数量
     * @param remark 备注
     * @return 是否成功
     */
    boolean confirmInbound(String id, String detailId, String actualWarehouseId, String actualLocationId, BigDecimal actualQuantity, String remark);

    /**
     * 取消入库单
     * @param id 入库单ID
     * @param remark 备注
     * @return 是否成功
     */
    boolean cancelInboundOrder(String id, String remark);

    /**
     * 更新入库单明细和库位状态
     * @param detail 明细信息
     * @param updateInventory 是否更新库存信息
     * @return 是否成功
     */
    boolean updateDetailWithLocationStatus(WmsInboundOrderDetail detail, Boolean updateInventory);

    /**
     * 保存额外库位明细
     * @param detail 明细信息
     * @param updateInventory 是否更新库存信息
     * @return 是否成功
     */
    boolean saveExtraLocationDetail(WmsInboundOrderDetail detail, Boolean updateInventory);

    /**
     * 批量确认入库
     * @param inboundOrderId 入库单ID
     * @param details 明细列表
     * @return 是否成功
     */
    boolean batchConfirmInbound(String inboundOrderId, List<Map<String, Object>> details);
    
    /**
     * 批量确认入库并更新库存历史记录
     * @param inboundOrderId 入库单ID
     * @param details 明细列表
     * @param params 附加参数，包含操作人、操作时间、是否更新成本等信息
     * @return 是否成功
     */
    boolean batchConfirmInboundWithHistory(String inboundOrderId, List<Map<String, Object>> details, Map<String, Object> params);

    /**
     * 入库成功后触发出库明细重新分配
     * @param inboundDetails 入库明细列表
     */
    void triggerOutboundReallocationAfterInbound(List<Map<String, Object>> inboundDetails);

    /**
     * 移动端入库单查询 - 支持折叠显示和模糊搜索
     * @param page 分页参数
     * @param query 查询条件
     * @return 分页结果
     */
    IPage<WmsInboundOrderVO> queryInboundOrderForMobile(Page<WmsInboundOrderVO> page, Map<String, Object> query);

    /**
     * 查询当前用户操作的入库单记录
     * @param page 分页参数
     * @param queryParam 查询条件
     * @param planInboundStartTime 计划入库开始时间
     * @param planInboundEndTime 计划入库结束时间
     * @param actualInboundStartTime 实际入库开始时间
     * @param actualInboundEndTime 实际入库结束时间
     * @param warehouseName 仓库名称
     * @param locationName 库位名称
     * @param materialCode 物料编码
     * @param materialName 物料名称
     * @return 用户操作的入库单记录
     */
    IPage<WmsInboundOrderVO> getUserOperationRecords(Page<WmsInboundOrderVO> page, WmsInboundOrder queryParam,
                                                   String planInboundStartTime, String planInboundEndTime,
                                                   String actualInboundStartTime, String actualInboundEndTime,
                                                   String warehouseName, String locationName,
                                                   String materialCode, String materialName,
                                                   List<String> statusList, List<String> businessTypeList);

    WmsInboundOrderVO getInboundOrderByIdAndUpdateBy(String id, String username);

    /**
     * 获取物料入库单总数
     * @return 物料入库单总数
     */
    Long getMaterialInboundOrderCount();

    /**
     * 获取物料出库单总数
     * @return 物料出库单总数
     */
    Long getMaterialOutboundOrderCount();

    /**
     * 根据采购到货信息自动生成采购入库单
     * @param purchaseOrderId 采购单ID
     * @param arrivalDate 到货日期
     * @param arrivalDetails 到货明细信息
     * @param username 操作用户
     * @return 生成的入库单ID，如果没有合格物料则返回null
     */
    String autoGenerateInboundOrderFromArrival(String purchaseOrderId, String arrivalDate, 
                                             List<Map<String, Object>> arrivalDetails, String username);

    /**
     * 解析余料入库单Excel文件
     * @param file Excel文件
     * @return 解析出的数据列表
     */
    List<Map<String, Object>> parseRemainingMaterialExcel(MultipartFile file);

    /**
     * 保存余料入库单导入数据
     */
    boolean saveRemainingMaterialInboundFromImport(List<Map<String, Object>> dataList, String createBy, String createByName);

    /**
     * 一键入库（余料入库单）
     */
    boolean oneClickInbound(String inboundOrderId, String username);
}